package framework.classification.entities.lattice.erca;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import com.googlecode.erca.Attribute;
import com.googlecode.erca.Entity;
import com.googlecode.erca.clf.Concept;

import framework.classification.entities.ClAbstractEntity;
import framework.classification.entities.ClFunctionProvided;
import framework.entity.ACLFunction;
import framework.entity.ACLInterface;

public class LatticeInterfaceProvidedErca extends LatticeAbstractErca {

	public void calculateReduced(ClAbstractEntity table) {

		conceptToExtends = new HashMap<String, ArrayList<String>>();
		realOperations = new HashMap<String, String>();
		abstractOperations = new HashMap<String, String>();
		String name = lattice.getName();
		for (int i = 0; i < lattice.getConcepts().size(); i++) {
			Concept concept = lattice.getConcepts().get(i);
			concept.setName("C"
					+ concept.getName().substring(
							concept.getName().indexOf("_") + 1));
			caculateOperationConcept(concept, table);
		}

	}

	public void caculateOperationConcept(Concept concept,
			ClAbstractEntity table) {

		// si la fonction deduite existe

		//soit le concept à un extent, dans ce cas il represente une interface deja definis
		if (!concept.getSimplifiedExtent().isEmpty()){
			for (Entity ent : concept.getSimplifiedExtent()){

				ACLInterface aclinter = new ACLInterface(ent.getName());
				aclinter.setFunctions(table.getAbstractClassfication().getStructure().getInterfacesFonction().get(ent.getName()));
				realOperations.put(aclinter.toString(),concept.getName());
				if (!conceptToExtends.containsKey(concept.getName()))
					conceptToExtends.put(concept.getName(),new ArrayList<String>());
				if (!conceptToExtends.get(concept.getName()).contains(aclinter.toString()))
					conceptToExtends.get(concept.getName()).add(aclinter.toString());

				if (lattice.getTop() == concept) superEntity = aclinter.toString();
			}

		}
		//soit les extents simplifies sont vide, dans ce cas on reconstruit la fonction abstraite
		//à partir des concepts parents;
		else{
			ACLInterface aclinter = new ACLInterface(table.getName()+concept.getName());


			for (Concept parentConcept : concept.getAllParents()){
				for (Attribute att : parentConcept.getSimplifiedIntent()){

					String funcAtt = att.getDescription();
					ArrayList<ACLFunction> remove = new ArrayList<ACLFunction>();
					ClFunctionProvided cl = table.getAbstractClassfication().getFunctionsProvided().get(funcAtt);
					Boolean add = true;
					for (ACLFunction funcinter : aclinter.getFunctions()){

						//on regarde si les fonctions de l'interface est parente de la fonction funcAtt
						if(cl.getLattice().isParent(funcinter.toString(),funcAtt)) remove.add(funcinter);
						else if (cl.getLattice().isParent(funcAtt,funcinter.toString())) add = false;
					}
					if (add){
						if (!remove.isEmpty()){

							for (ACLFunction r : remove){

								aclinter.getFunctions().remove(r);
							}

						}
						aclinter.getFunctions().add(new ACLFunction(funcAtt,ACLFunction.MODE2));
					}
				}

			}
			aclinter.setAbstract(true);
			if (!conceptToExtends.containsKey(concept.getName()))
				conceptToExtends.put(concept.getName(),new ArrayList<String>());
			if (!conceptToExtends.get(concept.getName()).contains(aclinter.toString()))
				conceptToExtends.get(concept.getName()).add(aclinter.toString());

		abstractOperations.put(aclinter.toString(),concept.getName());
		if (lattice.getTop() == concept) superEntity = aclinter.toString();
	}





}

}
